API Model for Stripe Service

We have set the background for modeling the API for Stripe by deciding on various technical aspects in the previous lesson. In this lesson, let’s dive deeper and model the Stripe API by discussing various endpoints, the request and response structure, and other relevant concepts.

Let's start by deciding the base URL for our API.

Base URL and endpoints#

We consider the following base URL for our proposed Stripe API that we will consider in the following sections:

The URL for the Stripe services
The URL for the Stripe services

Here, the api.stripe.com represents the domain while the v1.0 shows the API version. In our model, we consider v1.0 as the first version of our API. Similarly, service represents any service that our Stripe API provides to its users—for example, invoices, charges, refunds, and so on. We will also perform various operations using the given URL, so this will be a part of our discussion throughout this lesson.

Stripe consists of various services, and each service has multiple endpoints to operate on. Therefore, we have shown each endpoint in the following figure against each service for simplicity. You can unfold a specific branch's service details by clicking the filled dots (circles).

GET /refunds/?limit={count} HTTP/2.0
GET /refunds/refundId
POST /refunds HTTP/2.0
GET /charges/?limit={count} HTTP/2.0
GET /charges/{chargeId} HTTP/2.0
POST /charges HTTP/2.0
GET /customerSessions/?limit={count} HTTP/2.0
GET /customerSessions/{sessionId} HTTP/2.0
POST /customerSessions HTTP/2.0
DELETE /invoices/{invoiceId} HTTP/2.0
PUT /invoices/{invoiceId} HTTP/2.0
GET /invoices/?limit={count} HTTP/2.0
GET /invoices/{invoiceId} HTTP/2.0
POST /invoices HTTP/2.0
Retrieve a list of refunds
Retrieve a refund
Create refund
Retrieve a list of charges
Retrieve charge
Create charge
Retrieve a list of sessions
Retrieve session
Create session
Delete invoice
Update invoice
Retrieve a list of invoices
Retrieve invoice
Create invoice
Payout service
Balance service
Refunds service
Charges service
Session service
Invoices service
Customer service
Endpoints for multiple operations in the Stripe API

Note: Since most of the above endpoints perform similar operations, we discuss details of selected endpoints based on their significance to avoid redundant request-response messages. The rest of the services are summarized in the table at the end of this lesson.

Preconditions#

Prior to modeling API for Stripe, we have made the following assumptions:

  • The merchant account is already created, and the customers can easily transfer funds to their account, typically using the merchant's provided web application.

  • Any interaction of merchants with API uses the API keys for authentication.

  • For cross-origin requests, replace the Authorization with Bearer <token number>. The token number is provided upon registering and taking services of the API.

The message format for API endpoints#

Before tackling the request and response format of each endpoint, let's look at the important entities that need to be transferred in a request or can be received from the server in response.

The important data entities that are used in accessing Stripe endpoints for different services

Let’s begin with the request and response of each service’s endpoints in the following section. Due to the trivial nature of the customer service API, we have placed it in the following hint:

Customer service

Stripe needs to store customer information for processing recurring payments. We will use this service to perform tasks related to a customer—for example, creating, retrieving, updating, and deleting a customer’s personal and payment data, such as credit or debit card information. The requests and responses of each of these operations are discussed below.

Create a customer

  • HTTP methods: To create a customer for the first time, we need to use the POST HTTP method.

  • Request format: The request format is shown below in the HTTP and cURL formats for better readability and ease of understanding. The request takes data about a customer that includes the customer’s name, address, email, encrypted cardNumber, description to add more details about the customer, and so on.

    POST /v1.0/customers HTTP/2.0
    Host: api.stripe.com
    Content-Type: application/x-www-form- urlencoded
    X-API-Key: "API Key"
    Authorization: Bearer <JWT>
    Content-Length: xyz
    name={customerName}&cardInfo={EncryptedcardNumber}&description="more details"
  • Response format: The successful response from the server is shown below. The data in the body is in JSON format containing various customer attributes, including customerId, address, contact, balance, currency, timestamp, description, email, name, and so on.

    HTTP/2.0 200 OK
    Date: Sun, 25 Dec 2022 09:02:11 GMT
    Content-Type: text/json
    Transfer-Encoding: chunked
    //other essential headers
    {
      "customerId": "string",
      "address": null,
      "balance": 4000,
      "timestamp": 1405641986,
      "currency": "USD",
      "description": "Customer from US",
      "email": null,
      "name": null,
      "contact": null,
      "shipping": null,
      //other attributes
    }

Retrieve a customer

  • HTTP method: To retrieve customer data, the obvious choice is to use the GET HTTP method.

  • Request format: The request format is shown in the following code. The customerId is passed as a query parameter. The request doesn’t contain any body.

    GET /v1.0/customers/{customerId} HTTP/2.0
    Host: api.stripe.com
    X-API-Key: "API Key"
  • Response format: The response to retrieve customer data contains all the relevant fields of a customer. A successful response looks similar to the response to creating a customer in the above section.

Update a customer

  • HTTP method: To update a customer, we need to use the PUT method due to its idempotent nature.

  • Request format: The request format is shown below, where the customerId is passed as a query parameter for which we need to update the record. The following update request attempts to update the email field of the customer:

    PUT /v1.0/customers/{customerId} HTTP/2.0
    Host: api.stripe.com
    Content-Type: application/x-www-form-urlencoded
    Content-Length: xyz
    X-API-Key: "API Key"
    Authorization: Bearer <JWT>
    email=customer1@example.com
  • Response format: Upon execution of the update request, the response generated contains a success code and the customer data for which the record is updated. A sample response is shown below:

    HTTP/2.0 200 OK
    Date: Sun, 25 Dec 2022 09:02:11 GMT
    Content-Type: text/json
    Transfer-Encoding: chunked
    //other essential headers
    {
      "customerId": "string",
      "address": null,
      "balance": 4000,
      "timestamp": 1405641986,
      "currency": "USD",
      "description": "Customer from UK",
      "email": customer1@example.com,
      "invoicePrefix": "78TVBW8",
      "name": null,
      "contact": null,
      "shipping": null
      //other attributes
    }

Delete a customer

  • HTTP method: We can use the DELETE HTTP method to delete a customer’s data.

  • Request format: The request format is shown below, where the ID of the customer to be deleted is passed as a query parameter.

    DELETE /v1.0/customers/{customerId} HTTP/2.0
    Host: api.stripe.com
    X-API-Key: "API Key"
    Authorization: Bearer <JWT>
  • Response format: A successful response has a 204 status code to convey the message that the corresponding customer has been deleted from the record.

    HTTP/2.0 204 No Content 
    HOST: api.stripe.com

Note: We will discuss the create operation of the invoices, sessions, charges, and payout services. You can practice this with other services and their respective operations as well since multiple operations follow a similar pattern.

Invoices service#

The invoices service performs all the operations relevant to invoices, such as generating, updating, and deleting invoices. Let's look at the request and response of each operation the invoices service performs.

Create an invoice#

  • HTTP method: Since we will be creating the invoice for the first time, we need to use the POST method.

  • Request format: The request takes various parameters, including applicationCharges, tax, currency, customerId, description, and so on. The request to create an invoice is presented below:

The request format in HTTP to create an invoice
  • Response format: The response to the above request is shown below. It contains various attributes relevant to an invoice, such as dueAmount, paidAmount, applicationCharges, tax, description, and so on.

The response to create an invoice

Other operations of the invoice service are explained in the following hint:

Retrieve an invoice

  • HTTP method: The suitable HTTP method to retrieve any invoice data is to use the GET method.

  • Request format: The request to retrieve invoice details is shown below, which consists of the invoiceId that is passed as a query parameter.

    GET /v1.0/invoices/{invoiceId} HTTP/2.0
    HOST: api.stripe.com
    X-API-Key: "API Key"
  • Response format: The response format is similar to the response of creating an invoice via the POST method.

Update an invoice

  • HTTP method: Since we need to update an existing resource, the suitable option is to use the PUT HTTP method.

  • Request format: The request format consists of the parameters we want to update. For example, in the following request, we want to update the paidAmount, which also needs to modify the dueAmount.

    PUT /v1.0/invoices/{invoiceId} HTTP/2.0
    HOST: api.stripe.com
    X-API-Key: "API Key"
    Authorization: Bearer <JWT>
    Content-Type: application/x-www-form- urlencoded
    Content-Length: xyz 
    dueAmount=0&paidAmount=100
  • Response format: Upon successful execution of the delete request, the response from the server is shown below. The response consists of some information to convey a meaningful message to the user.

    HTTP/2.0 200 OK
    Date: Mon, 26 Dec 2022 15:23:34 GMT
    Content-Type: text/json
    {
     "invoiceId": {string},
     "customerId": {string},
     "dueAmount": 0,
     "paidAmount": 100,
     "currency":"USD"
    //other essential parameters
    }

Delete an invoice

  • HTTP method: The obvious choice to delete an invoice is to use the DELETE HTTP method.

  • Request format: The request format to delete an invoice is shown below, where the invoiceId for an invoice to be deleted is passed as a query parameter.

    DELETE /v1.0/invoices/{invoiceId} 
    HTTP/2.0
    HOST: api.stripe.com
    X-API-Key: "API Key"
    Authorization: Bearer <JWT>
  • Response format: Upon successful execution of the delete request, the response from the server is shown below. The response consists of some information to convey a meaningful message to the user.

    HTTP/2.0 200 OK 
    HOST: api.stripe.com
    Content-Type: application/json
    //body
    {
      "id": "invoiceId",
      "object": "invoice",
      "deleted": true
    }

Session service#

The session service creates and maintains a session in which customers aim to pay for a purchase. The merchant creates a session on the server and provides the session ID to the customer to begin payment.

Points to Ponder

Question 2

Stripe would charge the customer multiple times if a customer triggered multiple POST requests for a single purchase. How can we make the POST request idempotent to avoid the monetary loss of a customer?

Hide Answer

The POST method may cause inconsistency if repeated multiple times for a single purchase. To make the POST request idempotent, the client generates a key (also called an idempotency key) and sends it to the server with a request. If the customer encounters a network error, they can repeat the request with the same key. The server correlates the key with the earlier request(s) status. If the earlier requests were successfully processed, the server ignores the recent request and responds with a successful status to the customer. Otherwise, in case of failure of the earlier requests, the recent request is processed.

The process is explained in the following illustration. In the illustration on the left, we don’t use any idempotence key, so the same operation is performed twice, while in the illustration on the right side, the idempotence key prevents the same multiple operations from executing.

2 of 2

Create a session#

  • HTTP method: Since we need to create a new session each time a customer pays, we use the POST HTTP method.

  • Request format: The request format to create a customer session is shown below in the HTTP and cURL format. The request takes several parameters, including paymentMode, urlSuccess, urlCancel , charges, quantity, customerId, shippingInfo, and so on.

Note: The paymentMode indicates the one-time payment or periodic payment after a specific time (month or year).

The request format in HTTP to create a session

Note: Since we are using the x-www-form-urlencoded data format in our requests, we do not add any body tag after the HTTP headers. This is due to the fact that data in the x-www-form-urlencoded format is encoded in key-value pairs, which is similar to sending parameters as a query string in the URL.

  • Response format: The response in connection to the customer session request is shown below. The response includes various parameters—for example, the sessionId, customerId, timestamp, shippingInfo, and so on.

A response from the server while creating a session

Charges service#

The charges service creates charge details and is responsible for deducting the required amount from the credit or debit card.

Create a charge#

  • HTTP method: To create a new charge object, we need to use the POST method.

  • Request format: The request to create a charge consists of various parameters, as shown below.

Request format to create a charge object in HTTP
  • Response format: Upon successfully creating the charge, the response from the server contains all the parameters, as shown below:

A response to create a charge

Note: Other endpoints of the charges service are mentioned in the table at the end of this lesson.

Payout service#

The payout service manages all the operations when a merchant aims to transfer the amount from a Stripe account to a bank account.

Create a payout#

  • HTTP method: To create a new payout object, we need to use the POST method.

  • Request format: The request to create a payout consists of various parameters, as shown below.

Request format to create a payout object in HTTP
  • Response format: Upon successfully creating the payout, the response from the server contains all the parameters, as shown below:

A response to create a payout

Note: Other endpoints of the payout service are mentioned in the table at the end of this lesson.

Failed requests#

The table below presents some possible error responses that can arise while performing any of the above operations on the Stripe API:

Error Responses

Status Code

Phrase

Description

400

Bad Request

Indicates a general error when a request creates an invalid state (For example, missing data and domain validation errors)

401

Unauthorized

Represents a missing or invalid authentication token

402

Request Failed

Indicates that the parameters are valid but the request failed due to insufficient funds

403

Forbidden

Indicates that the customer cannot perform the operation

404

Not Found

Indicates that the requested resource is not available

409

Conflict

Indicates that there are two inflight requests with the same idempotence key

429

Too Many Requests

Indicates that the number of requests for a resource exceeds the maximum allowed requests

500

Internal Server Error

Indicates a general error when a backend server throws an exception

Summary#

The summary of each service, the relevant operations, endpoints, and other details that we described earlier in this lesson are mentioned in the following table:

Services

Operation

Endpoint

Data Entities

Response

(Status Code, Body)

Customer service


Create


POST /customers

name, address, email, cardNumber, and so on


201 Created, Yes

Retrieve a customer

GET /customers/{customerId}

Only customerId as a query parameter

200 OK, Yes

Update

PUT /customers/{customerId}

Parameters that need to be updated

200 OK, Yes

Delete

DELETE /customers/

{customerId}

Only customerId as a query parameter

204 No Content, No

Retrieve a list of customers

GET /customers/?limit={count} 

customerId and count as query parameters

200 OK, Yes

Invoice service


Create


POST /invoices

applicationCharges, tax, dueAmount, and so on


201 Created, Yes

Retrieve

GET /invoices/{invoiceId} 

Only invoiceId as a query parameter

200 OK, Yes

Retrieve a list of invoices

GET /invoices/?limit={count} HTTP/2.0

Only count as a query parameter

200 OK, Yes

Update

PUT /invoices/{invoiceId}

The parameters that need to be updated

200 OK, Yes

Delete

DELETE /invoices/{invoiceId}

Only invoiceId as a query parameter

204 No Content, No

Session service

Create

POST /customerSessions 

sessionId, paymentMode, shippingInfo, and so on

201 Created, Yes

Retrieve a session

GET /customerSessions/

{sessionId}

Only sessionId as a query parameter

200 OK, Yes

Retrieve a list of sessions

GET /customerSessions/?limit={count}

limit parameter passed in the query

200 OK, Yes

Charges service


Create


POST /charges

amount, billingDetails, customerId, invoiceId, and so on


201 Created, Yes

Retrieve

GET /charges/{chargeId}

Only chargeId as a query parameter

200 OK, Yes

Retrieve a list of charges

GET /charges/?limit={count} 

limit parameter passed in query

200 OK, Yes

Refunds service

Create

POST /refunds 

amount, chargeId, status, and so on

201 Created, Yes

Retrieve a refund

GET /refunds/refundId

refundId parameter passed in query

200 OK, Yes

Retrieve a list of refunds

GET /refunds/?limit={count} 

limit parameter passed in query

200 OK, Yes

Balance service

Retrieve balance

GET /balance/{balanceId} 

available, currency, accountDetails, and so on

200 OK, Yes

Retrieve a transaction

GET /balance/transactions/

{transactionId}

Only transactionId passed as a query parameter

200 OK, Yes

Retrieve a list of transactions

GET /balance/transactions/?limit={count}

limit parameter passed in query

200 OK, Yes

Payout service

Create

POST /payouts/

amount, depositTime, status, and so on

200 OK, Yes

Retrieve

GET /payouts/{payoutId}

payoutIdpassed in query

200 OK, Yes

Retrieve a list of payouts

GET /payouts/?limit={count}

limit parameter passed in query

200 OK, Yes

In this lesson, we have expanded various endpoints and the relevant operations via our proposed API calls. In the next lesson, we will discuss the interaction of Stripe with the cards network for various operations.

Stripe API Design Decisions

Stripe Interaction with Cards Network